#include <iostream>

enum class EntityCategory {
    BASE,
    EXTENDED,
    ASSOCIATED
};


//将enum class中的类型转换成string，同时也方便输出
std::string getCategoryString(EntityCategory category) {
    switch (category) {
        case EntityCategory::BASE: return "BASE";
        case EntityCategory::EXTENDED: return "EXTENDED";
        case EntityCategory::ASSOCIATED: return "ASSOCIATED";
        default: return "Unknown";
    }
}

// 基础模板类，用于递归地处理实体类型
template <EntityCategory...Categories>
class EntityType; 

// 基础模板类的偏特化，处理递归终止条件
template <>
class EntityType<> {
private:
    EntityCategory category;

public:
    EntityType() : category(EntityCategory::BASE) {}
    // EntityType() : category(EntityCategory& other) {}

    EntityCategory getCategory() const {
        return category;
    }
    friend std::ostream& operator<<(std::ostream& os, const EntityType&) {
        return os << "Base Entity Category: " << getCategoryString(EntityCategory::BASE);
    }

};

// 递归模板类的偏特化，处理多个实体类型的组合
template <EntityCategory First, EntityCategory... Rest>
class EntityType<First, Rest...> {
private:
    EntityCategory category;

public:
    EntityType() : category(First) {}

    EntityCategory getCategory() const {
        return category;
    }
    friend std::ostream& operator<<(std::ostream& os, const EntityType& entity) {
        return os << "Entity with category: " << getCategoryString(entity.getCategory());
    }
};

int main() {
    // 测试基础实体类型
    EntityType<> baseEntity;
    std::cout << "Base Entity Category: " << static_cast<int>(baseEntity.getCategory()) << std::endl;
    std::cout << "Base Entity Category: " << baseEntity << std::endl;

    // 测试拓展实体类型
    EntityType<EntityCategory::EXTENDED> extendedEntity;
    std::cout << "Extended Entity Category: " << static_cast<int>(extendedEntity.getCategory()) << std::endl;
    // std::cout << "Extended Entity Category: " << extendedEntity.getCategory() << std::endl;

    // 测试关联实体类型
    EntityType<EntityCategory::ASSOCIATED, EntityCategory::EXTENDED> associatedEntity;
    std::cout << "Associated Entity Category: " << static_cast<int>(associatedEntity.getCategory()) << std::endl;

    return 0;
}
